
#include <iostream>
#include <string>
using namespace std;
#include <pthread.h>
#include <unistd.h>

/*全局变量*/
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *start_routine(void *args)
{
    string message = static_cast<const char *>(args);
    while(true)
    {
        pthread_mutex_lock(&mutex);

        /*每个线程在打印消息之前都进入条件变量阻塞
         *这就是同步，每个线程都遵循一个特定的规则*/
        pthread_cond_wait(&cond,&mutex);
        cout << message << endl;
        pthread_mutex_unlock(&mutex);
    }
}

int main()
{
    pthread_t A,B;
    pthread_create(&A,nullptr,start_routine,(void *)"I am thread A");
    pthread_create(&B,nullptr,start_routine,(void *)"I am thread B");
    while(true)
    {
        usleep(1234);/*每隔一段时间唤醒一个线程*/
        pthread_cond_signal(&cond);
    }
    pthread_join(A,nullptr);
    pthread_join(B,nullptr);
    return 0;
}

















// #include <iostream>
// #include <vector>
// #include <string>
// using namespace std;
// #include <pthread.h>
// #include <unistd.h>
// #include "Mutex.hpp"
// using namespace ly;

// int tickets = 10000;

// /*将条件变量指针作为线程例程的参数*/
// struct threadData
// {
//     pthread_t _tid;
//     string _name;
//     pthread_mutex_t *_pmutex;
//     pthread_cond_t *_pcond;
// };

// void *getTickets(void *args)
// {
//     threadData *pd = static_cast<threadData *>(args);
//     while (true)
//     {
//         {
//             /*使用RAII风格的互斥锁
//              *每个线程访问临界资源之前先"排队"*/
//             LockGuard lockguard(pd->_pmutex);
//             pthread_cond_wait(pd->_pcond,pd->_pmutex);
//             if (tickets > 0)
//             {
//                 cout << pd->_name << " get tickets:" << tickets-- << endl;
//             }
//             else
//             {
//                 break;
//             }
//         }
//     }
//     return nullptr;
// }

// int main()
// {
//     vector<threadData *> vec;

//     /*互斥锁与条件变量的初始化*/
//     pthread_mutex_t lock;
//     pthread_mutex_init(&lock, nullptr);
//     pthread_cond_t cond;
//     pthread_cond_init(&cond,nullptr);

// #define NUM 4
//     for (int i = 0; i < NUM; i++)
//     {
//         threadData *td = new threadData;
//         td->_name = "thread" + to_string(i + 1);
//         td->_pmutex = &lock;
//         td->_pcond = &cond;
//         pthread_create(&td->_tid, nullptr, getTickets, td);
//         vec.push_back(td);
//     }

//     /*每隔1234微妙唤醒一个线程*/
//     while(true)
//     {
//         usleep(1234);
//         pthread_cond_signal(&cond);
//     }

//     for (auto &td : vec)
//     {
//         pthread_join(td->_tid, nullptr);
//         delete td;
//     }

//     /*互斥锁与条件变量的销毁*/
//     pthread_mutex_destroy(&lock);
//     pthread_cond_destroy(&cond);
//     return 0;
// }

// #include <iostream>
// #include <string>
// #include <memory>
// using namespace std;
// #include "Thread.hpp"
// using namespace ly;

// #include <unistd.h>

// void *start_routine(void *args)
// {
//     string name = static_cast<const char *>(args);
//     int cnt = 5;
//     while(cnt)
//     {
//         cout << name << " running...cnt: " << cnt-- << endl;
//         sleep(1);
//     }
//     pthread_exit((void *)666);
// }
// int main()
// {
//     unique_ptr<Thread> up(new Thread(start_routine,(void *)"thread 1"));

//     up->start();

//     void *ret = up->join();
//     cout << "return value: " << (long long)ret << endl;
//     return 0;
// }

// #include <iostream>
// #include <string>
// #include <cstring>
// #include <cerrno>
// using namespace std;
// #include <pthread.h>
// #include <unistd.h>

// /*线程局部存储变量*/
// __thread int global = 0;

// /*新线程对global递增，并且输出其值和地址*/
// void *thread_run(void *args)
// {
//     string name = static_cast<const char*>(args);
//     while(true)
//     {
//         cout << name << " running...global = " << global++ << " &global: " << &global << endl;
//         sleep(1);
//     }
//     return nullptr;
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid,nullptr,thread_run,(void *)"thread 1");

//     /*主线程打印global的值和地址但是不递增*/
//     while(true)
//     {
//         cout << "main thread running...global = " << global << " &global: " << &global << endl;
//         sleep(1);
//     }
//     return 0;
// }

// void *thread_run(void *args)
// {
//     string name = static_cast<const char*>(args);
//     int cnt = 3;
//     while(cnt)
//     {
//         cout << name << " running... cnt: " << cnt-- << endl;
//         sleep(1);
//     }
//     return nullptr;
// }

// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid,nullptr,thread_run,(void *)"thread 1");

//     /*主线程分离新线程*/
//     pthread_detach(tid);

//     /*主线程可以继续执行自己的任务*/
//     while(true)
//     {
//         cout << "main thread running..." << endl;
//         sleep(1);
//     }
//     return 0;
// }

// #include <iostream>
// #include <thread>// C++11的线程库
// using namespace std;
// #include <unistd.h>

// void start_routine()
// {
//     int cnt = 4;
//     while(cnt)
//     {
//         cout << "new thread...cnt :" << cnt-- << endl;
//         sleep(1);
//     }
// }

// int main()
// {
//     thread t1(start_routine);

//     t1.join();
//     cout << "new thread exit success" << endl;
//     return 0;
// }

// #include <pthread.h>
// #include <unistd.h>
// #include <iostream>
// #include <string>
// #include <vector>
// using namespace std;

// class pthread_data// 每个线程的数据块
// {
// public:
//     pthread_t _tid;
//     char _name[64];
// };

// void* start_routine(void* args)
// {
//     pthread_data* pd = static_cast<pthread_data*>(args);
//     int cnt = 3;
//     while(cnt)
//     {
//         cout << pd->_name << " cnt = " << cnt-- << " &cnt:" << &cnt << endl;
//         sleep(1);
//     }
//     // 在外部释放动态开辟的资源
//     //delete pd;// 防止内存泄漏
//     //return nullptr;
//     pthread_exit((void*)333);// 将整数333作为返回值
// }
// int main()
// {
//     vector<pthread_data*> vec;
// #define NUM 10
//     for(int i=0;i<NUM;i++)
//     {
//         // 即使pd一直在创建、销毁，但是pd当中保存的地址是堆上的不同位置
//         pthread_data* pd = new pthread_data();

//         // 给每个线程传入一个整型编号
//         snprintf(pd->_name,sizeof(pd->_name),"%s : %d","pthread",i+1);
//         pthread_create(&pd->_tid,nullptr,start_routine,(void*)pd);

//         vec.push_back(pd);// 将信息保存下来
//     }
//     sleep(1);// 先让新线程运行
//     for(int i=0;i<vec.size()/2;++i)// 取消一半新线程
//     {
//         pthread_cancel(vec[i]->_tid);
//         cout << vec[i]->_name << " cancel success" << endl;
//     }

//     for(auto& tid:vec)// 线程的tid已经被保存在了vector容器中
//     {
//         void* ret = nullptr;
//         pthread_join(tid->_tid,&ret);// 在内部将返回值写入ret
//         cout << tid->_name << " return value: " << (long long)ret << endl;
//         delete tid;// 释放动态开辟的资源
//     }
//     return 0;
// }

// // void* test(void* args)
// // {
// //     string name = static_cast<char*>(args);
// //     while(true)
// //     {
// //         cout << name << " running..." << endl;
// //         sleep(1);
// //         int* p = nullptr;
// //         *p = 333;// 对空指针解引用会导致运行崩溃
// //     }
// // }

// // int main()
// // {
// //     pthread_t tid;// 线程tid
// //     pthread_create(&tid,nullptr,test,(void*)"pthread one");// 创建新线程

// //     // 主线程
// //     while(true)
// //     {
// //         printf("main pthread running...\n");
// //         sleep(1);
// //     }
// //     return 0;
// // }